// .NET Framework Namespaces
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

//NUnit Namespaces
using NUnit.Framework;

// Project Namespaces
using RNChessRulesEngine;
using RNChessRulesEngine.RNChessRulesExceptions;
using RNChessBoardCommonTypes;

namespace RNChessBoard.RNChessRulesEngine.TestFixtures
{
    [TestFixture(Description =
        "This class contains tests for the ChessRulesEngine class.")]
    public class ChessRulesEngineTestFixture : BaseChessRulesEngineTestFixture
    {
        [Test]
        public void MakeMove_D2D4_Valid()
        {
            // White queen's pawn opening - should be a valid move.
            PlayerMoveResult pmr = _chessRulesEngine.MakeMove("D2", "D4");
            Assert.AreEqual(MoveResult.LEGAL, pmr.PlayerMoveStatus,
                "Unexpected post-move result after opening with D2-D4.");
        }

        [Test]
        public void MakeMove_OpenE2E5_Illegal()
        {
            // White king's pawn opening, moving three squares forward - ILLEGAL
            PlayerMoveResult pmr = _chessRulesEngine.MakeMove("E2", "E5");

            Assert.AreEqual(MoveResult.ILLEGAL, pmr.PlayerMoveStatus,
                "Unexpected post-move result after opening with E2-E5");
        }

        [Test]
        public void MakeMove_OpenKingPawnE3E4_Illegal()
        {
            // Attempt to move king's pawn that doesn't exist.
            PlayerMoveResult pmr = _chessRulesEngine.MakeMove("E3", "E4");

            Assert.AreEqual(MoveResult.ILLEGAL, pmr.PlayerMoveStatus,
                "Unexpected post-move result after opening with E3-E4");
        }

        [Test, ExpectedException(typeof(System.ArgumentException))]
        public void MakeMove_OpenA9A10_BadArguments()
        {
            PlayerMoveResult pmr = _chessRulesEngine.MakeMove("A9", "A10");
        }

        /// <summary>
        /// Tests playback of Capablanca v. Mieses 1913 if played to mate for white.
        /// </summary>
        [Test]
        public void MakeMove_PlayWMateCapablancaMieses1913_Legal()
        {
            ReplayTestGame(ClassicTestGames.Capablanca_Mate_Mieses_1913);
        }

        /// <summary>
        /// Tests playback of my own "coffeehouse" game against myself to mate for white.
        /// </summary>
        [Test]
        public void MakeMove_PlayWMateCoffeeHouseCRC_Legal()
        {
            ReplayTestGame(ClassicTestGames.CRC_CoffeeHouse_WhiteToMate);
        }

        /// <summary>
        /// Tests playback of Golombek v. Brown 1949 to black resignation - features
        /// white en passant capture at move #16.
        /// </summary>
        [Test]
        public void MakeMove_PlayBResignEPCaptureGolombekBrown1949_Legal()
        {
            ReplayTestGame(ClassicTestGames.Golombek_Brown_Resigns_EPCapture);
        }

        /// <summary>
        /// Tests standard white pawn openings for all files from second rank to
        /// third rank and second rank to fourth rank.
        /// </summary>
        [Test]
        public void MakeMove_AllWhitePawnOpenings_Legal()
        {
            ReplayTestGameBattery(WhitePawnTestMoves.WhitePawnOpenings_Rank3_Rank4_Legal);
        }

        /// <summary>
        /// Tests standard black pawn responses for all files from seventh rank to
        /// sixth rank and seventh rank to fifth rank.
        /// </summary>
        [Test]
        public void MakeMove_AllBlackPawnOpenings_Legal()
        {
            ReplayTestGameBattery(BlackPawnTestMoves.BlackPawnOpenings_Rank6_Rank5_Legal);
        }

        /// <summary>
        /// Tests illegal white pawn openings for all files to the fifth rank.
        /// </summary>
        [Test]
        public void MakeMove_WhitePawnOpeningsFifthRank_Illegal()
        {
            ReplayTestGameBattery(WhitePawnTestMoves.WhitePawnOpenings_Rank5_Illegal);
        }

        /// <summary>
        /// Tests illegal white pawn openings for all files to the third rank diagonally.
        /// </summary>
        [Test]
        public void MakeMove_WhitePawnOpeningsThirdRankDiagonals_Illegal()
        {
            ReplayTestGameBattery(WhitePawnTestMoves.WhitePawnOpenings_Rank3Diagonal_Illegal);
        }

        [Test]
        public void MakeMove_TestGamesBattery()
        {
            ReplayTestGameBattery(WhitePawnTestMoves.TestBattery_Legal);
        }
    }
}
